package com.example.ercmssystem2.service.impl;

import com.example.ercmssystem2.entity.Department;
import com.example.ercmssystem2.entity.Resource;
import com.example.ercmssystem2.entity.ResourceType;
import com.example.ercmssystem2.entity.User;
import com.example.ercmssystem2.repository.DepartmentRepository;
import com.example.ercmssystem2.repository.ResourceRepository;
import com.example.ercmssystem2.repository.ResourceTypeRepository;
import com.example.ercmssystem2.repository.UserRepository;
import com.example.ercmssystem2.service.ResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Transactional
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ResourceRepository resourceRepository;

    @Autowired
    private ResourceTypeRepository resourceTypeRepository;

    @Autowired
    private DepartmentRepository departmentRepository;

    @Autowired
    private UserRepository userRepository;

    @Override
    public Resource createResource(Resource resource, Long createdBy) {
        // 验证资源名称唯一性
        if (!isResourceNameUnique(resource.getName(), null)) {
            throw new RuntimeException("资源名称已存在");
        }

        // 验证资源类型是否存在
        if (resource.getResourceType() == null || resource.getResourceType().getId() == null) {
            throw new RuntimeException("资源类型不能为空");
        }
        Optional<ResourceType> resourceType = resourceTypeRepository.findById(resource.getResourceType().getId());
        if (resourceType.isEmpty()) {
            throw new RuntimeException("资源类型不存在");
        }

        // 验证部门是否存在（如果指定了部门）
        if (resource.getDepartmentId() != null) {
            Optional<Department> department = departmentRepository.findById(resource.getDepartmentId());
            if (department.isEmpty() || !department.get().getEnabled()) {
                throw new RuntimeException("部门不存在或已禁用");
            }
        }

        // 验证创建者是否存在
        Optional<User> creator = userRepository.findById(createdBy);
        if (creator.isEmpty() || !creator.get().getEnabled()) {
            throw new RuntimeException("创建者不存在或已禁用");
        }

        resource.setCreatedBy(createdBy);
        return resourceRepository.save(resource);
    }

    @Override
    public Resource updateResource(Long id, Resource resource) {
        Optional<Resource> existingResource = resourceRepository.findById(id);
        if (existingResource.isEmpty()) {
            throw new RuntimeException("资源不存在");
        }

        Resource existing = existingResource.get();
        
        // 验证资源名称唯一性（排除当前资源）
        if (!isResourceNameUnique(resource.getName(), id)) {
            throw new RuntimeException("资源名称已存在");
        }

        // 验证资源类型是否存在
        if (resource.getResourceType() != null && resource.getResourceType().getId() != null) {
            Optional<ResourceType> resourceType = resourceTypeRepository.findById(resource.getResourceType().getId());
            if (resourceType.isEmpty()) {
                throw new RuntimeException("资源类型不存在");
            }
        }

        // 验证部门是否存在（如果指定了部门）
        if (resource.getDepartmentId() != null) {
            Optional<Department> department = departmentRepository.findById(resource.getDepartmentId());
            if (department.isEmpty() || !department.get().getEnabled()) {
                throw new RuntimeException("部门不存在或已禁用");
            }
        }

        existing.setName(resource.getName());
        existing.setResourceType(resource.getResourceType());
        existing.setDescription(resource.getDescription());
        existing.setStatus(resource.getStatus());
        existing.setLocation(resource.getLocation());
        existing.setDepartmentId(resource.getDepartmentId());

        return resourceRepository.save(existing);
    }

    @Override
    public void deleteResource(Long id) {
        Optional<Resource> resource = resourceRepository.findById(id);
        if (resource.isEmpty()) {
            throw new RuntimeException("资源不存在");
        }

        // 检查资源是否正在使用中
        if ("IN_USE".equals(resource.get().getStatus())) {
            throw new RuntimeException("资源正在使用中，无法删除");
        }

        resourceRepository.deleteById(id);
    }

    @Override
    public Resource getResourceById(Long id) {
        Optional<Resource> resource = resourceRepository.findById(id);
        if (resource.isEmpty()) {
            throw new RuntimeException("资源不存在");
        }
        
        Resource res = resource.get();
        enrichResourceInfo(res);
        return res;
    }

    @Override
    public List<Resource> getAllResources() {
        List<Resource> resources = resourceRepository.findAll();
        resources.forEach(this::enrichResourceInfo);
        return resources;
    }

    @Override
    public List<Resource> getResourcesByDepartment(Long departmentId) {
        List<Resource> resources = resourceRepository.findByDepartmentId(departmentId);
        resources.forEach(this::enrichResourceInfo);
        return resources;
    }

    @Override
    public List<Resource> getResourcesByStatus(String status) {
        List<Resource> resources = resourceRepository.findByStatus(status);
        resources.forEach(this::enrichResourceInfo);
        return resources;
    }

    @Override
    public List<Resource> getResourcesByType(Long resourceTypeId) {
        Optional<ResourceType> resourceType = resourceTypeRepository.findById(resourceTypeId);
        if (resourceType.isEmpty()) {
            throw new RuntimeException("资源类型不存在");
        }
        
        List<Resource> resources = resourceRepository.findByResourceType(resourceType.get());
        resources.forEach(this::enrichResourceInfo);
        return resources;
    }

    @Override
    public List<Resource> getUserManageableResources(Long userId) {
        Optional<User> user = userRepository.findById(userId);
        if (user.isEmpty() || !user.get().getEnabled()) {
            return List.of();
        }

        User currentUser = user.get();
        
        // 系统管理员可以管理所有资源
        if ("ADMIN".equals(currentUser.getRole())) {
            return getAllResources();
        }

        // 部门管理员只能管理自己部门的资源
        if ("DEPT_MANAGER".equals(currentUser.getRole())) {
            List<Resource> resources = resourceRepository.findResourcesByUserDepartments(userId);
            resources.forEach(this::enrichResourceInfo);
            return resources;
        }

        return List.of();
    }

    @Override
    public List<Resource> getAvailableResourcesByDepartment(Long departmentId) {
        List<Resource> resources = resourceRepository.findAvailableResourcesByDepartment(departmentId);
        resources.forEach(this::enrichResourceInfo);
        return resources;
    }

    @Override
    public List<Resource> findAvailableResources() {
        List<Resource> resources = resourceRepository.findByStatus("AVAILABLE");
        resources.forEach(this::enrichResourceInfo);
        return resources;
    }

    @Override
    public Resource assignResourceToDepartment(Long resourceId, Long departmentId) {
        Optional<Resource> resource = resourceRepository.findById(resourceId);
        if (resource.isEmpty()) {
            throw new RuntimeException("资源不存在");
        }

        if (departmentId != null) {
            Optional<Department> department = departmentRepository.findById(departmentId);
            if (department.isEmpty() || !department.get().getEnabled()) {
                throw new RuntimeException("部门不存在或已禁用");
            }
        }

        Resource res = resource.get();
        res.setDepartmentId(departmentId);
        return resourceRepository.save(res);
    }

    @Override
    public Resource updateResourceStatus(Long resourceId, String status) {
        Optional<Resource> resource = resourceRepository.findById(resourceId);
        if (resource.isEmpty()) {
            throw new RuntimeException("资源不存在");
        }

        // 验证状态值
        if (!isValidStatus(status)) {
            throw new RuntimeException("无效的资源状态");
        }

        Resource res = resource.get();
        res.setStatus(status);
        return resourceRepository.save(res);
    }

    @Override
    public boolean isResourceNameUnique(String name, Long excludeId) {
        if (excludeId == null) {
            return !resourceRepository.findByName(name).isPresent();
        } else {
            return !resourceRepository.existsByNameAndIdNot(name, excludeId);
        }
    }

    @Override
    public boolean hasResourcePermission(Long userId, Long resourceId) {
        Optional<User> user = userRepository.findById(userId);
        if (user.isEmpty() || !user.get().getEnabled()) {
            return false;
        }

        User currentUser = user.get();
        
        // 系统管理员拥有所有权限
        if ("ADMIN".equals(currentUser.getRole())) {
            return true;
        }

        // 部门管理员检查
        if ("DEPT_MANAGER".equals(currentUser.getRole())) {
            List<Resource> manageableResources = getUserManageableResources(userId);
            return manageableResources.stream().anyMatch(resource -> resource.getId().equals(resourceId));
        }

        return false;
    }

    @Override
    public List<ResourceType> getAllResourceTypes() {
        return resourceTypeRepository.findAll();
    }

    @Override
    public ResourceType createResourceType(ResourceType resourceType) {
        if (resourceTypeRepository.existsByName(resourceType.getName())) {
            throw new RuntimeException("资源类型名称已存在");
        }
        return resourceTypeRepository.save(resourceType);
    }

    @Override
    public ResourceType updateResourceType(Long id, ResourceType resourceType) {
        Optional<ResourceType> existingType = resourceTypeRepository.findById(id);
        if (existingType.isEmpty()) {
            throw new RuntimeException("资源类型不存在");
        }

        ResourceType existing = existingType.get();
        
        // 检查名称唯一性（排除当前类型）
        if (!existing.getName().equals(resourceType.getName()) && 
            resourceTypeRepository.existsByName(resourceType.getName())) {
            throw new RuntimeException("资源类型名称已存在");
        }

        existing.setName(resourceType.getName());
        existing.setDescription(resourceType.getDescription());

        return resourceTypeRepository.save(existing);
    }

    @Override
    public void deleteResourceType(Long id) {
        Optional<ResourceType> resourceType = resourceTypeRepository.findById(id);
        if (resourceType.isEmpty()) {
            throw new RuntimeException("资源类型不存在");
        }

        // 检查是否有资源使用此类型
        List<Resource> resources = resourceRepository.findByResourceType(resourceType.get());
        if (!resources.isEmpty()) {
            throw new RuntimeException("该资源类型下还有资源，无法删除");
        }

        resourceTypeRepository.deleteById(id);
    }

    // 私有方法：丰富资源信息
    private void enrichResourceInfo(Resource resource) {
        // 填充部门名称
        if (resource.getDepartmentId() != null) {
            Optional<Department> department = departmentRepository.findById(resource.getDepartmentId());
            department.ifPresent(dept -> resource.setDepartmentName(dept.getName()));
        }
        
        // 填充资源类型名称
        if (resource.getResourceType() != null) {
            resource.setResourceTypeName(resource.getResourceType().getName());
        }
        
        // 填充创建者姓名
        if (resource.getCreatedBy() != null) {
            Optional<User> creator = userRepository.findById(resource.getCreatedBy());
            creator.ifPresent(user -> resource.setCreatedByName(user.getRealName()));
        }
    }

    // 私有方法：验证资源状态
    private boolean isValidStatus(String status) {
        return "AVAILABLE".equals(status) || 
               "IN_USE".equals(status) || 
               "MAINTENANCE".equals(status) || 
               "RETIRED".equals(status);
    }
    
    // ========== 统计分析相关方法实现 ==========
    
    @Override
    public Map<String, Object> getResourceUtilizationStatistics(LocalDateTime start, LocalDateTime end) {
        Map<String, Object> stats = new HashMap<>();
        
        // 获取所有资源
        List<Resource> allResources = resourceRepository.findAll();
        
        // 资源状态概览
        Map<String, Long> statusDistribution = allResources.stream()
            .collect(Collectors.groupingBy(Resource::getStatus, Collectors.counting()));
        stats.put("statusDistribution", statusDistribution);
        
        // 按资源类型统计
        Map<String, Long> typeDistribution = allResources.stream()
            .filter(r -> r.getResourceType() != null)
            .collect(Collectors.groupingBy(r -> r.getResourceType().getName(), Collectors.counting()));
        stats.put("typeDistribution", typeDistribution);
        
        // 按部门统计
        Map<String, Long> departmentDistribution = allResources.stream()
            .filter(r -> r.getDepartmentId() != null)
            .collect(Collectors.groupingBy(r -> {
                Optional<Department> dept = departmentRepository.findById(r.getDepartmentId());
                return dept.map(Department::getName).orElse("未知部门");
            }, Collectors.counting()));
        stats.put("departmentDistribution", departmentDistribution);
        
        // 资源利用率计算
        long totalResources = allResources.size();
        long availableResources = statusDistribution.getOrDefault("AVAILABLE", 0L);
        long inUseResources = statusDistribution.getOrDefault("IN_USE", 0L);
        long maintenanceResources = statusDistribution.getOrDefault("MAINTENANCE", 0L);
        
        double utilizationRate = totalResources > 0 ? (double) inUseResources / totalResources * 100 : 0.0;
        double availabilityRate = totalResources > 0 ? (double) availableResources / totalResources * 100 : 0.0;
        double maintenanceRate = totalResources > 0 ? (double) maintenanceResources / totalResources * 100 : 0.0;
        
        stats.put("totalResources", totalResources);
        stats.put("availableResources", availableResources);
        stats.put("inUseResources", inUseResources);
        stats.put("maintenanceResources", maintenanceResources);
        stats.put("utilizationRate", utilizationRate);
        stats.put("availabilityRate", availabilityRate);
        stats.put("maintenanceRate", maintenanceRate);
        
        // 热点区域资源覆盖（基于位置统计）
        Map<String, Long> locationDistribution = allResources.stream()
            .filter(r -> r.getLocation() != null && !r.getLocation().trim().isEmpty())
            .collect(Collectors.groupingBy(Resource::getLocation, Collectors.counting()));
        stats.put("locationDistribution", locationDistribution);
        
        // 资源周转时间（简化版本，基于状态变化）
        // 这里可以根据实际业务逻辑计算资源从使用到恢复可用的平均时间
        stats.put("averageTurnaroundTime", 0.0); // 待实现
        
        return stats;
    }
} 